package hch.redesFerroviarias;

import hch.utils.Sentido;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Tren extends Thread {
	private int id;
	private int nroEstacion;
	private int capacidadMax;
	private int capacidadActual;
	private Sentido sentido;
	private List<Estacion> estaciones = RedFerroviaria.ESTACIONES;
	private List<Pasajero> pasajeros  = new ArrayList<Pasajero>();
	
	public Tren(int id, Sentido sentido, int numeroEstacion, int capMax){
		this.id      = id;
		this.sentido = sentido;
		this.nroEstacion  = numeroEstacion;
		this.capacidadMax = capMax;
		this.capacidadActual = 0;
	}
	
	//*************//
	//** METHODS **//
	//*************//
	public void agregarPasajero(Pasajero pasajero) {
		this.pasajeros.add(pasajero);
		this.capacidadActual ++;
	}
	
	public void removerPasajero(Pasajero pasajero){
		this.pasajeros.remove(pasajero);
		this.capacidadActual --;
	}
	
	public void setProximaEstacion(){
		if(this.sentido == Sentido.DERECHA){
			if(this.nroEstacion == estaciones.size())
				this.nroEstacion = 1;
			else
				this.nroEstacion++;
		}else{
			if(this.nroEstacion == 1)
				this.nroEstacion = estaciones.size();
			else 
				this.nroEstacion--;
		}
	}
	
	public void subirPasajeros(){
		RedFerroviaria.LOCK.lock();
		RedFerroviaria.CONDICIONES[this.nroEstacion-1].signalAll();
		RedFerroviaria.LOCK.unlock();
	}
	
	public void bajarPasajeros(){
		RedFerroviaria.LOCK.lock();
		List<Pasajero> pasajeros = new ArrayList<Pasajero>();
		pasajeros.addAll(this.pasajeros);
		for(Pasajero p: pasajeros){
			if(p.getEstacionDestino() == this.getNroEstacion()){
				this.capacidadActual--;
				this.pasajeros.remove(p);
				p.getEstaEnViaje().signal();
			}
		}
		RedFerroviaria.LOCK.unlock();
	}
		
	public void run() {
		while (true) {
			try {
				Estacion estacion = this.estaciones.get(this.nroEstacion - 1);
				estacion.removeTren(this);
				this.setProximaEstacion();
				estacion = this.estaciones.get(this.nroEstacion - 1);
				Thread.sleep(new Random().nextInt(3000)); //Viaje
				//agrego al tren en espera en el sentido indicado
				RedFerroviaria.LOCK.lock();
				if(this.sentido == Sentido.DERECHA)
					estacion.getTrenesEsperandoDer().add(this);
				else
					estacion.getTrenesEsperandoIzq().add(this);
				RedFerroviaria.LOCK.unlock();
				
				estacion.obetenerAnden();
				
				//quito al tren en espera en el sentido indicado
				RedFerroviaria.LOCK.lock();
				if(this.sentido == Sentido.DERECHA)
					estacion.getTrenesEsperandoDer().remove(this);
				else
					estacion.getTrenesEsperandoIzq().remove(this);
				RedFerroviaria.LOCK.unlock();
				
				estacion.addTren(this);
				RedFerroviaria.imprimirEstado();
				bajarPasajeros();
				subirPasajeros();
				Thread.sleep(RedFerroviaria.TiempoDeEspera);
				estacion.dejarAnden();
				RedFerroviaria.imprimirEstado();
			} catch (InterruptedException e) {}
		}
	}
	
	//**************//
	//** ACCESORS **//
	//**************//
	public int getNroEstacion() {
		return nroEstacion;
	}
	
	public int getCapacidadMax() {
		return capacidadMax;
	}
	
	public int getCapacidadActual() {
		return capacidadActual;
	}
	
	public Sentido getSentido() {
		return sentido;
	}

	@Override
	public String toString() {
		return "T"+id+"("+this.capacidadActual+"/"+this.capacidadMax+")";
	}
}
